package com.cedric.yixianpai.game;

import com.cedric.yixianpai.game.Constants.CardType;
import com.cedric.yixianpai.game.Status.DuelBuff;
import com.cedric.yixianpai.game.Status.DuelStatus;
import com.cedric.yixianpai.server.Utils.CardFactory;
import com.cedric.yixianpai.server.Utils.CardVo;
import com.cedric.yixianpai.server.Utils.GameInfoDTO;
import com.cedric.yixianpai.server.Utils.GameResult;
import com.cedric.yixianpai.game.characters.TuKui;
import com.cedric.yixianpai.game.interfaces.Card;


import javax.naming.InitialContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 定义对局信息
 */
public class Duel {

    private final DuelStatus p1stStatus;//todo:将name提取出来
    private final DuelStatus p2ndStatus;
    private final List<Card> p1stCards;
    private final List<Card> p2ndCards;
    private int p1Index = 0;
    private int p2Index = 0;
    private int turn = 0;

    /**
     * new Duel
     * 进行初始化对局状态与卡组
     */
    public Duel(GameInfoDTO gameInfoDTO) throws NoSuchMethodException {
        this.p1stStatus = new DuelStatus(gameInfoDTO.getP1InfoDTO().getName(),gameInfoDTO.getP1InfoDTO().getHp());
        this.p2ndStatus = new DuelStatus(gameInfoDTO.getP2InfoDTO().getName(),gameInfoDTO.getP2InfoDTO().getHp());
        p1stCards=new ArrayList<>();
        p2ndCards=new ArrayList<>();
        for (CardVo cardVo : gameInfoDTO.getP1Cards()) {
            CardFactory cardFactory = new CardFactory();
            Card newcard = cardFactory.createCard(cardVo.getTitle(), cardVo.getLvl());//利用CardFactory创建类
//            System.out.println(newcard.getTitle()+" lvl:"+newcard.getLevel());
            p1stCards.add(newcard);
        }
        for (CardVo cardVo : gameInfoDTO.getP2Cards()) {
            CardFactory cardFactory = new CardFactory();
            Card newcard = cardFactory.createCard(cardVo.getTitle(), cardVo.getLvl());//利用CardFactory创建类
//            System.out.println(newcard.getTitle()+" lvl:"+newcard.getLevel());
            p2ndCards.add(newcard);
        }
//        System.out.println("对局初始化成功！");
    }

    /**
     * 处理一个p1对局回合
     */
    public void p1Turn(int index) {
        //获取卡片
        Card p1Card = p1stCards.get(index);
        //云剑柔心效果
        int yunCure = p1stStatus.getPlayerBuff().getYun_Cure();
        if (p1Card.getCardType() == CardType.YUN && yunCure > 0) {
            p1stStatus.getPlayerHp().addHp(yunCure);
        }
        //连云次数
        if (p1stStatus.getPlayerBuff().getLastUseType() == CardType.YUN && p1Card.getCardType() == CardType.YUN) {
            p1stStatus.getPlayerBuff().addYun_Consecutive();
        } else {
            p1stStatus.getPlayerBuff().clearYun_Consecutive();
        }
        //打印消息
//        System.out.println(p1stStatus.getPlayerName() + "使用了" + p1Card.getTitle());
        // 处理卡片逻辑
        p1Card.effect(p1stStatus, p2ndStatus);
        //处理白鸟灵剑诀
        dealBaiNiaoLingJianJue(p1stStatus, p1stCards);
        //记录卡牌
        p1stStatus.getPlayerBuff().recordLastType(p1Card.getCardType());
        //在cards中删除持续牌
        if (p1Card.isSustained()) {
            p1stCards.remove(index);
            //reset p1Index
            p1Index = index - 1;
        }
        dealLianHuanJianZhen(p1stStatus, p1Card.getCardType(), index, true);
    }

    //处理百鸟灵剑诀
    private void dealBaiNiaoLingJianJue(DuelStatus pStatus, List<Card> deck) {
        int dec = pStatus.getPlayerBuff().getBaiNiaoLJ();
        if (dec > 0) {
            for (Card card : deck) {
                if (card.getCardType() == CardType.LING) {
                    card.setSpiritNeed(Math.max(0, card.getSpiritNeed() - dec));
                }
            }
            pStatus.getPlayerBuff().clearBaiNiaoLingJianJue();
        }
    }

    //处理连环剑阵
    private void dealLianHuanJianZhen(DuelStatus pStatus, CardType pCardType, int index, boolean is1flag) {
        if (pStatus.getPlayerBuff().isLHJZ()) {//连环剑阵
            int JZIndex = pStatus.getPlayerBuff().getJZIndex();
            if (JZIndex == -1) {
//                System.out.println("未触发连环剑阵!");
            } else {
//                System.out.println("触发连环剑阵!");
                if (is1flag) {
//                    System.out.println("使用" + p1stCards.get(JZIndex).getTitle());
                    p1stCards.get(JZIndex).effect(p1stStatus, p2ndStatus);
                } else {
//                    System.out.println("使用" + p2ndCards.get(JZIndex).getTitle());
                    p2ndCards.get(JZIndex).effect(p2ndStatus, p1stStatus);
                }
                pStatus.getPlayerBuff().resetLHJZ();
                return;
            }
        }
        pStatus.getPlayerBuff().resetLHJZ();
        //记录剑阵
        if (pCardType == CardType.ZHEN) {
            pStatus.getPlayerBuff().setJZIndex(index);
        }
    }

    public void p2Turn(int index) {
        Card p2Card = p2ndCards.get(index);
//        System.out.println(p2ndStatus.getPlayerName() + "使用了" + p2Card.getTitle());
        //云剑柔心效果
        int yunCure = p2ndStatus.getPlayerBuff().getYun_Cure();
        if (p2Card.getCardType() == CardType.YUN && yunCure > 0) {
            p2ndStatus.getPlayerHp().addHp(yunCure);
        }
        //连云次数
        if (p2ndStatus.getPlayerBuff().getLastUseType() == CardType.YUN && p2Card.getCardType() == CardType.YUN) {
            p2ndStatus.getPlayerBuff().addYun_Consecutive();
        } else {
            p2ndStatus.getPlayerBuff().clearYun_Consecutive();
        }
        //effect
        p2Card.effect(p2ndStatus, p1stStatus);

        dealBaiNiaoLingJianJue(p2ndStatus, p2ndCards);

        p2ndStatus.getPlayerBuff().recordLastType(p2Card.getCardType());//记录卡牌
        //在cards中删除持续牌
        if (p2Card.isSustained()) {
            p2ndCards.remove(index);
            //reset
            p2Index = index - 1;
        }
        dealLianHuanJianZhen(p2ndStatus, p2Card.getCardType(), index, false);
    }

    /**
     * 开始对局
     */
    public GameResult startFight() {
        while (turn <= 10) {
//            System.out.println("------------");
//            System.out.println("Turn " + turn);
//            System.out.println("------------");
//            System.out.println("p1Index = " + p1Index + ", p2Index = " + p2Index);
            p1stStatus.getPlayerBuff().BeforeTurn();//p1状态迭代
            this.p1Turn(p1Index % p1stCards.size());
            //如果回合停留，索引不增加
            if (p1stStatus.isTurnStop()) {
                p1stStatus.cancelTurnStop();
            } else {
                p1Index += 1;
                //没有被停留若触发再动
                if (p1stStatus.isAgain()) {
//                    System.out.println("==》触发再动");
                    this.p1Turn(p1Index % p1stCards.size());
                    p1stStatus.resetAgain();
                    if (p1stStatus.isTurnStop()) {
                        p1stStatus.cancelTurnStop();
                    } else {
                        p1Index += 1;
                    }
                }
            }

            if (!p1stStatus.survive() || !p2ndStatus.survive()) {
                return new GameResult(getWinner(), turn, p1stStatus.getPlayerName(), p2ndStatus.getPlayerName(), p1stStatus.getPlayerHp().getHp(), p2ndStatus.getPlayerHp().getHp());
            }
            p2ndStatus.getPlayerBuff().BeforeTurn();//p2状态迭代
            this.p2Turn(p2Index % p2ndCards.size());
            if (p2ndStatus.isTurnStop()) {
                p2ndStatus.cancelTurnStop();
            } else {
                p2Index += 1;
                //没有被停留若触发再动
                if (p2ndStatus.isAgain()) {
//                    System.out.println("==》触发再动");
                    this.p2Turn(p2Index % p2ndCards.size());
                    p2ndStatus.resetAgain();
                    if (p2ndStatus.isTurnStop()) {
                        p2ndStatus.cancelTurnStop();
                    } else {
                        p2Index += 1;
                    }
                }
            }
            turn += 1;

            if (!p1stStatus.survive() || !p2ndStatus.survive()) {
                return new GameResult(getWinner(), turn, p1stStatus.getPlayerName(), p2ndStatus.getPlayerName(), p1stStatus.getPlayerHp().getHp(), p2ndStatus.getPlayerHp().getHp());
            }
        }
        return null;
    }


    public String getWinner() {
        int ph1 = p1stStatus.getPlayerHp().getHp(), ph2 = p2ndStatus.getPlayerHp().getHp();
        if (ph1 == ph2) {//血量相同随机判负
            Random r = new Random();
            int rInt = r.nextInt(2);
            return rInt == 1 ? p1stStatus.getPlayerName() : p2ndStatus.getPlayerName();
        }
        return ph1 > ph2 ? p1stStatus.getPlayerName() : p2ndStatus.getPlayerName();
    }
}
